home *** CD-ROM | disk | FTP | other *** search
- /*
- * $RCSfile: redoLHash.C,v $
- * $Revision: 1.1.1.1 $
- * $Date: 1996/05/04 21:55:58 $
- */
- /**********************************************************************
- * EXODUS Database Toolkit Software
- * Copyright (c) 1991 Computer Sciences Department, University of
- * Wisconsin -- Madison
- * All Rights Reserved.
- *
- * Permission to use, copy, modify and distribute this software and its
- * documentation is hereby granted, provided that both the copyright
- * notice and this permission notice appear in all copies of the
- * software, derivative works or modified versions, and any portions
- * thereof, and that both notices appear in supporting documentation.
- *
- * THE COMPUTER SCIENCES DEPARTMENT OF THE UNIVERSITY OF WISCONSIN --
- * MADISON ALLOWS FREE USE OF THIS SOFTWARE IN ITS "AS IS" CONDITION.
- * THE DEPARTMENT DISCLAIMS ANY LIABILITY OF ANY KIND FOR ANY DAMAGES
- * WHATSOEVER RESULTING FROM THE USE OF THIS SOFTWARE.
- *
- * The EXODUS Project Group requests users of this software to return
- * any improvements or extensions that they make to:
- *
- * EXODUS Project Group
- * c/o David J. DeWitt and Michael J. Carey
- * Computer Sciences Department
- * University of Wisconsin -- Madison
- * Madison, WI 53706
- *
- * or exodus@cs.wisc.edu
- *
- * In addition, the EXODUS Project Group requests that users grant the
- * Computer Sciences Department rights to redistribute these changes.
- **********************************************************************/
- #include "BTREEPAGE.h"
- #include "LH_Log.h"
- #include "bf_macro.h"
- #include "redo_intfuncs.h"
-
-
- #ifdef DEBUG
- extern void (*BT_PrintFunc)(int len, char* key);
-
- static void IntPrint(int /* kLen */, char* key)
- {
- fprintf(stderr, "%d", *((int*) key));
- }
-
- #endif /* BT_DEBUG */
-
-
-
- void redoLHash(LOGRECORDHDR* recHdr)
- {
- redoLHash_fr(recHdr);
- }
-
- void redoLHash_fr(LOGRECORDHDR* recHdr)
- {
-
- TRPRINT(TR_IO|TR_LOG, TR_LEVEL_1, ("lsn:%d", recHdr->recordLSN.offset));
-
- PID* pid = & recHdr->actionPid;
- TRPRINT(TR_IO|TR_LOG, TR_LEVEL_2, ("pid:%d", pid->page));
-
- //
- // Check to see if the operation needs to be redone
- //
- GROUPLINK* gLink;
- if (!redoCheckPage(recHdr, &gLink, PAGE_INDEX)) {
- //
- // Don't need to redo
- //
- TRPRINT(TR_RECOVER, TR_LEVEL_2, ("dirty page not present"));
- return;
- }
- CHECK_GROUPLINK_MAGIC(gLink);
-
- LHDIRPAGE* dirp = (LHDIRPAGE*) gLink->bufFrame;
- LHINDPAGE* indp = (LHINDPAGE*) gLink->bufFrame;
-
- //
- // redo
- //
- void* vptr = GET_LOG_IMAGE(recHdr, 0);
- LH_TRACE(("R(%d,%d): ", recHdr->recordLSN.offset, pid->page));
-
- switch (recHdr->action) {
- BT_Tuple* tp;
- BT_Tuple tmp;
- int keyExists;
- TWO slot;
- int i;
-
-
- case LOG_ACTION_LHASH_DIRPAGE_INIT:
- {
- LogDirPageInitData* rp = (LogDirPageInitData*) vptr;
- LH_TRACE(("redo directory page init for pid %d\n", pid->page));
- dirp->Init(*pid, rp->rootFlag, rp->keyType);
- }
- break;
-
- case LOG_ACTION_LHASH_INDEXPAGE_INIT:
- {
- LogIndexPageInitData* rp = (LogIndexPageInitData*) vptr;
- LH_TRACE(("redo index page init for pid %d\n", pid->page));
- indp->Init(*pid, rp->hashVal, rp->keyType, rp->ovFlag);
- }
- break;
-
- case LOG_ACTION_LHASH_PHYSIC_INSERT:
- {
- LogLhashPhysicInsertData* rp =
- (LogLhashPhysicInsertData*) vptr;
- ASSERT3(rp->startSlot >= 0 && rp->numSlots > 0);
- char* buff = rp->data;
- LH_TRACE(("redo index page physic insert in page: %d", pid->page));
- for (i = rp->startSlot; i < rp->startSlot+rp->numSlots; i++) {
- tp = (BT_Tuple*) buff;
- LH_TRACE((" %d", * (int*) tp->KeyValue()));
- indp->InsertTuple(*tp, i);
- buff += tp->Size();
- }
- if (!indp->OvLabel())
- indp->SetLoad(indp->LoadComp());
- LH_TRACE(("\n"));
- }
- break;
-
- case LOG_ACTION_LHASH_PHYLOG_INSERT:
- {
- LogLhashPhyLogInsertData* rp =
- (LogLhashPhyLogInsertData*) vptr;
- ASSERT3(rp->numSlots > 0);
- char* buff = rp->data;
- PFC func = SMCOMPFUNC[indp->KeyType()];
-
- LH_TRACE(("redo index page physiological insert in page: %d", pid->page));
- for (i = 0; i < rp->numSlots; i++) {
- tp = (BT_Tuple*) buff;
- LH_TRACE((" %d", * (int*) tp->KeyValue()));
- if (indp->Search(tp->KeyLen(), tp->KeyValue(), func,slot)) {
- ASSERT3(FALSE);
- }
- else {
- indp->InsertTuple(*tp, slot);
- }
- buff += tp->Size();
- }
- if (!indp->OvLabel())
- indp->SetLoad(indp->LoadComp());
- LH_TRACE(("\n"));
- }
- break;
-
- case LOG_ACTION_LHASH_PHYSIC_DELETE:
- {
- LogLhashPhysicDeleteData* rp =
- (LogLhashPhysicDeleteData*) vptr;
- ASSERT3(rp->startSlot >= 0 && rp->numSlots > 0);
- LH_TRACE(("redo index page physic delete in page: %d", pid->page));
- for (i = rp->startSlot + rp->numSlots - 1;
- i >= rp->startSlot; i--) {
- LH_TRACE((" %d", *(int*) indp->Tuple(i).KeyValue()));
- indp->RemoveTuple(i);
- }
- if (!indp->OvLabel())
- indp->SetLoad(indp->LoadComp());
- LH_TRACE(("\n"));
- }
- break;
-
- case LOG_ACTION_LHASH_PHYLOG_DELETE:
- {
- LogLhashPhyLogDeleteData* rp =
- (LogLhashPhyLogDeleteData*) vptr;
- ASSERT3(rp->numSlots > 0);
- char* buff = rp->data;
- PFC func = SMCOMPFUNC[indp->KeyType()];
-
- LH_TRACE(("redo index page physiological delete in page: %d", pid->page));
- for (i = 0; i < rp->numSlots; i++) {
- tp = (BT_Tuple*) buff;
- LH_TRACE((" %d", * (int*) tp->KeyValue()));
- if (!indp->Search(tp->KeyLen(), tp->KeyValue(), func,slot)){
- ASSERT3(FALSE);
- }
- else {
- indp->RemoveTuple(slot);
- }
- buff += tp->Size();
- }
- if (!indp->OvLabel())
- indp->SetLoad(indp->LoadComp());
- LH_TRACE(("\n"));
- }
- break;
-
- case LOG_ACTION_LHASH_LOGIC_INSERT:
- {
- LogLhashLogicInsertData* rp =
- (LogLhashLogicInsertData*) vptr;
-
- keyExists = indp->Search(rp->keyLen, rp->Key(),
- SMCOMPFUNC[rp->keyType],slot);
- LH_TRACE(("redo index page logic insert %d in page %d\n",
- * (int*) rp->Key(), pid->page));
- ASSERT3(rp->elSize > 0 && rp->elSize <= SM_MAXELEMLEN);
- if (keyExists) {
- ASSERT1(!rp->unique);
- if (indp->AddElem(slot, rp->El())) {
- SM_ERROR(TYPE_FATAL, Active->errno);
- }
- }
- else {
- tmp.Create(rp->keyLen, rp->Key(), rp->El(), rp->elSize);
- indp->InsertTuple(tmp, slot);
- if (!indp->OvLabel())
- indp->SetLoad(indp->LoadComp());
- }
- ASSERT3(indp->CheckContent());
- }
- break;
-
-
- case LOG_ACTION_LHASH_LOGIC_DELETE:
- {
- LogLhashLogicDeleteData* rp =
- (LogLhashLogicDeleteData*) vptr;
-
- keyExists = indp->Search(rp->keyLen, rp->Key(),
- SMCOMPFUNC[rp->keyType],slot);
-
- LH_TRACE(("redo index page logic delete %d in page %d\n",
- * (int*) rp->Key(), pid->page));
- ASSERT1(keyExists);
- ASSERT3(indp->Tuple(slot).KeyLen() == rp->keyLen);
- ASSERT3((SMCOMPFUNC[rp->keyType])(rp->keyLen, rp->Key(),
- rp->keyLen, indp->Tuple(slot).KeyValue()) == 0);
- ASSERT3( rp->elSize > 0 && rp->elSize <= SM_MAXELEMLEN);
- if (indp->RemoveElem(slot, rp->El())) {
- SM_ERROR(TYPE_FATAL, Active->errno);
- }
- if (indp->Tuple(slot).ElCnt() == 0) {
- indp->RemoveTuple(slot);
- if (!indp->OvLabel())
- indp->SetLoad(indp->LoadComp());
- }
- ASSERT3(indp->CheckContent());
- }
- break;
-
- case LOG_ACTION_LHASH_SET_INDEX_OVERFLOW:
- {
- LogSetIndexOverflowData* rp =
- (LogSetIndexOverflowData*) vptr;
- LH_TRACE(("redo set index page overflow in page %d\n", pid->page));
- indp->SetPageOverflow(rp->newOvPage);
- }
- break;
-
- case LOG_ACTION_LHASH_RESET_INDEX_OVERFLOW:
- {
- LogResetIndexOverflowData* rp =
- (LogResetIndexOverflowData*) vptr;
- LH_TRACE(("redo reset index page overflow in page %d\n", pid->page));
- indp->ResetPageOverflow(rp->keepFlag);
- }
- break;
-
- case LOG_ACTION_LHASH_DIR_UPDATE:
- {
- LogDirUpdateData* rp = (LogDirUpdateData*) vptr;
- LH_TRACE(("redo directory page split update in page %d\n", pid->page));
- if (rp->growFlag)
- dirp->IndSplitUpdate(rp->oldFromLoad, rp->fromLoad,
- rp->toLoad);
- else
- dirp->IndShrinkUpdate(rp->fromLoad, rp->toLoad,
- rp->oldFromLoad);
- }
- break;
-
- case LOG_ACTION_LHASH_DIR_LOAD_UPDATE:
- {
- LogDirLoadUpdateData* rp =
- (LogDirLoadUpdateData*) vptr;
- LH_TRACE(("redo directory page load update in page %d\n", pid->page));
- dirp->LoadUpdate(rp->load1,rp->load2);
- }
- break;
-
- case LOG_ACTION_LHASH_DIR_SET_NEXT_ENTRY:
- {
- LogDirSetNextEntryData* rp =
- (LogDirSetNextEntryData*) vptr;
- LH_TRACE(("redo directory page set next entry in page %d hval %d\n", pid->page, rp->hashVal));
- if (rp->newPage==NULLPID-1) {
- dirp->UnSetNextEntry(rp->hashVal);
- }
- else {
- if (rp->hashVal < dirp->CurPos())
- dirp->SetEntry(rp->newPage, rp->hashVal);
- else
- dirp->SetNextEntry(rp->newPage);
- }
- }
- break;
-
- case LOG_ACTION_LHASH_DIR_ROOT_CTRL:
- {
- LogDirRootCtrlData* rp = (LogDirRootCtrlData*) vptr;
- LH_TRACE(("redo directory page update ctrl in page %d\n", pid->page));
- dirp->lhDirCtrl.M = rp->M;
- dirp->lhDirCtrl.P = rp->P;
- dirp->lhDirCtrl.I = rp->I;
- dirp->lhDirCtrl.curPos = rp->curPos;
- dirp->lhDirCtrl.height = rp->height;
- dirp->lhDirCtrl.load = rp->load;
- }
- break;
-
- case LOG_ACTION_LHASH_SET_THRESHOLD:
- {
- LogSetThresholdData* rp = (LogSetThresholdData*) vptr;
- dirp->SetThreshold(rp->newThreshold);
- }
- break;
-
- case LOG_ACTION_LHASH_DIR_SPLIT_COPY:
- {
- LogDirSplitData* rp =
- (LogDirSplitData*) vptr;
- LH_TRACE(("redo directory page split copy in page %d\n", pid->page));
- dirp->lhDirCtrl.height = (ONE) rp->height;
- dirp->lhDirCtrl.curPos = rp->curPos;
- BCOPY(rp->data, dirp->indPid,
- (int)rp->curPos*sizeof(SHORTPID));
- }
- break;
-
- case LOG_ACTION_LHASH_DIR_SPLIT_RESET:
- {
- LogDirSplitData* rp =
- (LogDirSplitData*) vptr;
- LH_TRACE(("redo directory page split reset in page %d\n", pid->page));
- dirp->DirSplitUpdate();
- dirp->SetNextEntry(rp->newPage1);
- dirp->SetNextEntry(rp->newPage2);
- }
- break;
-
- case LOG_ACTION_LHASH_LOGIC_INCR_OIDCNT:
- {
- LogLhashLogicIncrElCntData* rp =
- (LogLhashLogicIncrElCntData*) vptr;
-
- keyExists = indp->Search(rp->keyLen, rp->Key(),
- SMCOMPFUNC[rp->keyType],slot);
- ASSERT1(keyExists);
- ASSERT3(indp->Tuple(slot).KeyLen() == rp->keyLen);
- ASSERT3((SMCOMPFUNC[rp->keyType])(rp->keyLen, rp->Key(),
- rp->keyLen, indp->Tuple(slot).KeyValue()) == 0);
- LH_TRACE(("redo ++oidcnt\n"));
- indp->Tuple(slot).IncrElCnt();
- }
- break;
-
- case LOG_ACTION_LHASH_LOGIC_DECR_OIDCNT:
- {
- LogLhashLogicDecrElCntData* rp =
- (LogLhashLogicDecrElCntData*) vptr;
-
- keyExists = indp->Search(rp->keyLen, rp->Key(),
- SMCOMPFUNC[rp->keyType],slot);
- ASSERT1(keyExists);
- ASSERT3(indp->Tuple(slot).KeyLen() == rp->keyLen);
- ASSERT3((SMCOMPFUNC[rp->keyType])(rp->keyLen, rp->Key(), rp->
- keyLen, indp->Tuple(slot).KeyValue()) == 0);
-
- LH_TRACE(("redo --oidcnt\n"));
- indp->Tuple(slot).DecrElCnt();
- }
- break;
-
- case LOG_ACTION_LHASH_LOGIC_SET_OVERFLOW:
- {
- LogLhashLogicSetOverflowData* rp =
- (LogLhashLogicSetOverflowData*) vptr;
-
- keyExists = indp->Search(rp->keyLen, rp->KeyValue(),
- SMCOMPFUNC[rp->keyType], slot);
- ASSERT1(keyExists);
- tp = & indp->Tuple(slot);
- ASSERT3(tp->KeyLen() == rp->keyLen);
- ASSERT3(tp->ElCnt() == rp->numEl);
- ASSERT3((SMCOMPFUNC[rp->keyType])(rp->keyLen, rp->KeyValue(),
- rp->keyLen, tp->KeyValue()) == 0);
- LH_TRACE(("redo set overflow\n"));
- indp->SetOverflow(slot, rp->ovPid);
- }
- break;
-
- case LOG_ACTION_LHASH_LOGIC_RESET_OVERFLOW:
- {
- LogLhashLogicSetOverflowData* rp =
- (LogLhashLogicSetOverflowData*) vptr;
-
- keyExists = indp->Search(rp->keyLen, rp->KeyValue(),
- SMCOMPFUNC[rp->keyType], slot);
- ASSERT1(keyExists);
- tp = & indp->Tuple(slot);
- ASSERT3(tp->KeyLen() == rp->keyLen);
- ASSERT3(tp->ElCnt() == rp->numEl);
- ASSERT3((SMCOMPFUNC[rp->keyType])(rp->keyLen, rp->KeyValue(),
- rp->keyLen, tp->KeyValue()) == 0);
-
- LH_TRACE(("redo reset overflow\n"));
- indp->SetUnderflow(slot, rp->numEl, rp->ElList());
- }
- break;
- case LOG_ACTION_LHASH_OV_CONVERT:
- {
- LogLhashOvConvertData* rp =
- (LogLhashOvConvertData*) vptr;
- LH_TRACE(("redo convert overflow in page %d\n", pid->page));
- indp->OvConvert(rp->newHashVal, rp->cvtFlag);
- }
- break;
- default:
- SM_ERROR(TYPE_FATAL, esmINTERNAL);
- }
-
- if (recHdr->action == LOG_ACTION_LHASH_DIR_UPDATE ||
- recHdr->action == LOG_ACTION_LHASH_DIR_LOAD_UPDATE ||
- recHdr->action == LOG_ACTION_LHASH_DIRPAGE_INIT ||
- recHdr->action == LOG_ACTION_LHASH_DIR_SET_NEXT_ENTRY ||
- recHdr->action == LOG_ACTION_LHASH_DIR_SPLIT_COPY ||
- recHdr->action == LOG_ACTION_LHASH_DIR_SPLIT_RESET ||
- recHdr->action == LOG_ACTION_LHASH_DIR_ROOT_CTRL ||
- recHdr->action == LOG_ACTION_LHASH_SET_THRESHOLD
- ) {
- dirp->lrc() = recHdr->actionLRC;
- }
- else {
- ASSERT3(indp->CheckContent());
- indp->lrc() = recHdr->actionLRC;
- }
-
- signalSemaphore(&gLink->pageHash->semaphore);
-
- bf_UnfixPage(gLink, BF_DEFAULT, TRUE);
- }
-
-